package io.gitee.loulan_yxq.owner.poi.excel.entity;

import io.gitee.loulan_yxq.owner.core.tool.ObjectTool;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.apache.poi.ss.usermodel.*;

import java.util.function.Function;

/*********************************************************
 ** excel得表头配置信息
 ** <br><br>
 ** Date: Created in 2022/9/1 10:54
 ** @author loulan
 ** @version 0.0.0
 *********************************************************/
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelHeaderConfiguration {
    // 该表头形式得名称
    private String name = "-";

    // 对应属性的key
    private String key;

    // 当前表头所在得位置（可以是合并得单元格）
    private Position position;

    // 水平方式（居中，居左，居右）
    private HorizontalAlignment horizontalAlignment;
    // 垂直方式（居中，居左，居右）
    private VerticalAlignment verticalAlignment;

    // 字体大小（配置/20 才能和excel中得一样）
    private Short fontSize;
    // 是否加粗，加黑
    private Boolean bold;

    // 当前列的宽度，如何是合并单元格
    private Integer width;

    // 数据处理器（优先使用这个处理器，如果这个不存在，那么就是用全局的处理器）
    private Function<Object, String> dataHandler;

    /**
     * 获取当前表头得样式
     *
     * @param workbook excel工作簿
     * @return 样式对象
     * @author :loulan
     */
    public CellStyle getCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        Font font = workbook.createFont();
        if (ObjectTool.isNotNull(horizontalAlignment))
            cellStyle.setAlignment(horizontalAlignment);
        if (ObjectTool.isNotNull(verticalAlignment))
            cellStyle.setVerticalAlignment(verticalAlignment);
        if (ObjectTool.isNotNull(fontSize))
            font.setFontHeight(fontSize);
        if (ObjectTool.isNotNull(bold))
            font.setBold(bold);
        cellStyle.setFont(font);
        return cellStyle;
    }

    /*********************************************************
     ** 构建者类
     ** <br><br>
     ** Date: Created in 2022/9/1 16:32
     ** @author loulan
     ** @version 0.0.0
     *********************************************************/
    public static class Builder {
        private ExcelHeaderConfiguration excelHeaderConfiguration;

        private Builder(ExcelHeaderConfiguration excelHeaderConfiguration) {
            this.excelHeaderConfiguration = excelHeaderConfiguration;
        }

        /**
         * 表头的构建者对象
         *
         * @return 构建者对象
         * @author :loulan
         */
        public static Builder builder() {
            return new Builder(new ExcelHeaderConfiguration());
        }

        /**
         * 设置表头的名称
         *
         * @param name 名称
         * @return 构建者对象
         * @author :loulan
         */
        public Builder name(String name) {
            excelHeaderConfiguration.name = name;
            return this;
        }

        /**
         * 设置该表头对象数据的属性key
         *
         * @param key 属性key
         * @return 构建者对象
         * @author :loulan
         */
        public Builder key(String key) {
            excelHeaderConfiguration.key = key;
            return this;
        }

        /**
         * 设置列的宽度（这里参数输入当前列放入字符的个数就可以【字符大小为默认大小的时候】）
         *
         * @param width 字符个数，也可以列宽
         * @return 构建对象
         * @author :loulan
         */
        public Builder width(int width) {
            // 这里*256就是为了字符，默认大小的字符，一个就是256
            excelHeaderConfiguration.width = width * 256;
            return this;
        }

        /**
         * 设置该表头所在的位置。这里可以进行单元格的合并
         *
         * @param startRow  开始行
         * @param endRow    结束行
         * @param startCell 开始列
         * @param endCell   结束列
         * @return 构建者对象
         * @author :loulan
         */
        public Builder position(int startRow, int endRow, int startCell, int endCell) {
            excelHeaderConfiguration.position = new Position(startRow, endRow, startCell, endCell);
            return this;
        }

        /**
         * 设置该表头所在的位置
         *
         * @param row  所在行
         * @param cell 所在列
         * @return 构建者对象
         * @author :loulan
         */
        public Builder position(int row, int cell) {
            return position(row, row, cell, cell);
        }

        /**
         * 设置表头的对象方式
         *
         * @param horizontalAlignment 水平对齐方式
         * @param verticalAlignment   垂直对齐方式
         * @return 构建者对象
         * @author :loulan
         */
        public Builder alignment(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
            excelHeaderConfiguration.horizontalAlignment = horizontalAlignment;
            excelHeaderConfiguration.verticalAlignment = verticalAlignment;
            return this;
        }

        /**
         * 设置该表头的字体
         *
         * @param fontSize 字体大小
         * @param bold     是否加粗
         * @return 构建者对象
         * @author :loulan
         */
        public Builder font(short fontSize, boolean bold) {
            //字体大小（配置/20 才能和excel中得一样），所以如果参数是14（和excel一样），那么*20才能匹配上
            excelHeaderConfiguration.fontSize = (short) (fontSize * 20);
            excelHeaderConfiguration.bold = bold;
            return this;
        }

        /**
         * 设置该表头所在列的数据的数据处理器。该处理器优先于全局处理器执行，如果该处理器不存在，那么就会执行全局处理器
         *
         * @param dataHandler 列数据处理器
         * @return 构建者对象
         * @author :loulan
         */
        public Builder dataHandler(Function dataHandler) {
            excelHeaderConfiguration.dataHandler = dataHandler;
            return this;
        }

        /**
         * 构建excel的表头配置对象
         *
         * @return excel的表头配置对象
         * @author :loulan
         */
        public ExcelHeaderConfiguration build() {
            // 如果没有设置位置，那么默认位置就是0000
            if (ObjectTool.isNull(excelHeaderConfiguration.position)) {
                excelHeaderConfiguration.position = new Position(0, 0, 0, 0);
            }

            return excelHeaderConfiguration;
        }
    }
}
